package com.zjitc.utils.listener;

import com.rabbitmq.client.AMQP.BasicProperties;
import com.rabbitmq.client.*;
import com.zjitc.common.Gsonal;
import com.zjitc.common.redis.RedisCache;
import com.zjitc.dao.CollectDao;
import com.zjitc.dao.ExpressDao;
import com.zjitc.dao.OrderDao;
import com.zjitc.dao.ProductDao;
import com.zjitc.pojo.*;
import com.zjitc.utils.Mail;
import com.zjitc.utils.Utils;
import com.zjitc.vo.ForgetPasswordDemo;
import com.zjitc.vo.UserOrder;
import com.zjitc.vo.UserPath;
import com.zjitc.vo.order.OrderInfo;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.context.support.WebApplicationContextUtils;

import javax.mail.MessagingException;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * Create by IntelliJ IDEA
 *
 * @author: jsonor
 * @date-Time: 2018/4/19 16:54
 * @description:
 */
@SuppressWarnings("ALL")
public class ListenerQueue implements ServletContextListener {

  private final String Update_Product = "Update_Product";
  private final String Update_Orders = "Update_Orders";
  private final String Queue_Add = "Queue_Add";
  private final String Queue_Del = "Queue_Del";
  private final String Queue_Email = "Queue_Email";
  private final String ForgetPassword = "ForgetPassword";
  private final String Add_Collect = "AddCollect";
  private final String Del_Collect = "DelCollect";

  @Override
  @Autowired
  public void contextInitialized(ServletContextEvent sce) {
    OrderDao orderDao = WebApplicationContextUtils.getWebApplicationContext(sce.getServletContext())
        .getBean(OrderDao.class);
    ProductDao productDao = WebApplicationContextUtils
        .getWebApplicationContext(sce.getServletContext()).getBean(ProductDao.class);
    ExpressDao edao = WebApplicationContextUtils.getWebApplicationContext(sce.getServletContext())
        .getBean(ExpressDao.class);
    ConnectionFactory factory = WebApplicationContextUtils
        .getWebApplicationContext(sce.getServletContext()).getBean(ConnectionFactory.class);
    RedisCache redis = WebApplicationContextUtils.getWebApplicationContext(sce.getServletContext())
        .getBean(RedisCache.class);
    CollectDao collectDao = WebApplicationContextUtils
        .getWebApplicationContext(sce.getServletContext()).getBean(CollectDao.class);

    mythread(factory, collectDao, productDao, orderDao, edao, redis);
  }

  /**
   * Receives notification that the ServletContext is about to be shut down. <p> <p>All servlets and
   * filters will have been destroyed before any ServletContextListeners are notified of context
   * destruction.
   *
   * @param sce the ServletContextEvent containing the ServletContext that is being destroyed
   */
  @Override
  public void contextDestroyed(ServletContextEvent sce) {

  }

  public void mythread(
      ConnectionFactory factory, CollectDao collectDao,
      ProductDao productDao, OrderDao orderDao, ExpressDao edao,
      RedisCache redis) {
    try {
      Connection connection = factory.newConnection();
      Channel channel = connection.createChannel();
      //添加订单
      Consumer consumer1 = new DefaultConsumer(channel) {
        @Override
        public void handleDelivery(String consumerTag, Envelope envelope,
            BasicProperties properties,
            byte[] body) throws IOException {
          String tojson = new String(body);
          OrderInfo info = Gsonal.fromJson(tojson, OrderInfo.class);
          Orders orders = info.getOrder();
          try {
            if (orders.getOrderitems().size() != 0) {
              orderDao.addorder(orders);
              try {
                orderDao.addorderitem(orders.getOrderitems());
              } catch (Exception e) {
                e.printStackTrace();
              }

              System.out.println("添加到订单成功：订单号" + orders.getOid());
            }
          } catch (Exception e) {
            e.printStackTrace();
            channel.basicNack(envelope.getDeliveryTag(), false, true);
            System.out.println("处理中出错");
          } finally {
            channel.basicAck(envelope.getDeliveryTag(), false);
          }
        }
      };

      //删除操作
      Consumer consumer2 = new DefaultConsumer(channel) {
        @Override
        public void handleDelivery(
            String consumerTag, Envelope envelope,
            BasicProperties properties, byte[] body) throws IOException {
          String tojson = new String(body);
          OrderInfo info = Gsonal.fromJson(tojson, OrderInfo.class);
          String oid = info.getOid();
          orderDao.deleteorderitem(oid);
          try {
            Express check = edao.check(oid);
            if (check != null) {
              edao.delete(oid);
            }
          } catch (Exception e) {
            e.printStackTrace();
          }
          orderDao.deleteorder(oid);
          System.out.println("成功删除订单：" + oid);
          channel.basicAck(envelope.getDeliveryTag(), false);
        }
      };

      //发送邮件
      Consumer consumer3 = new DefaultConsumer(channel) {
        @Override
        public void handleDelivery(String consumerTag, Envelope envelope,
            BasicProperties properties,
            byte[] body) throws IOException {
          System.out.println(
              "--------------------------------进入发送注册----------------------------------------------------------------------------------");
          UserPath up = Gsonal.fromJson(new String(body), UserPath.class);
          Mail mail = new Mail();
          String path = up.getPath();
          User user = up.getUser();
          String url = "";
          url = "http://localhost:8080" + path + "/user/active.do?uid=" + user.getUid() + "&code="
              + user.getCode();
          StringBuilder builder = new StringBuilder(1024);
          builder.append("<h3>").append("激活邮件，点击以下链接进行账号激活").append("</h3>");
          builder.append("<a href='").append(url).append("'>").append(url).append("</a>");
          try {
            mail.send(user.getEmail(), "激活邮件", builder.toString());
            System.out.println("发送邮件成功");
          } catch (MessagingException e) {
            throw new RuntimeException(e);
          }
        }
      };

      //发送验证码
      Consumer consumer4 = new DefaultConsumer(channel) {
        @Override
        public void handleDelivery(String consumerTag, Envelope envelope,
            BasicProperties properties, byte[] body) throws IOException {
          System.out.println(
              "--------------------------------进入发送验证码----------------------------------------------------------------------------------");
          String json = new String(body);
          ForgetPasswordDemo demo = Gsonal.fromJson(json, ForgetPasswordDemo.class);
          Mail mail = new Mail();
          String url = Utils.forgetcode();
          redis.set(demo.getUsername(), url);
          redis.expire(demo.getUsername(), 60 * 5);
          StringBuilder builder = new StringBuilder(1024);
          builder.append("<h3>").append("商城验证，您的验证码是：").append("</h3>");
          builder.append(url).append("\n").append("您的验证码5分钟内有效");
          try {
            mail.send(demo.getEmail(), "重置密码申请", builder.toString());
            System.out.println("发送忘记邮件成功");
          } catch (MessagingException e) {
            throw new RuntimeException(e);
          }
        }
      };

      //支付后更新商品
      Consumer consumer5 = new DefaultConsumer(channel) {
        @Override
        public void handleDelivery(String consumerTag, Envelope envelope,
            BasicProperties properties,
            byte[] body) throws IOException {
          String json = new String(body);
          Product product = Gsonal.fromJson(json, Product.class);
          productDao.update(product);
          System.out.println("支付后更新商品成功");
        }
      };

      //更新orders
      Consumer consumer6 = new DefaultConsumer(channel) {
        @Override
        public void handleDelivery(String consumerTag, Envelope envelope,
            BasicProperties properties, byte[] body) throws IOException {
          String json = new String(body);
          Orders order = Gsonal.fromJson(json, Orders.class);
          orderDao.update(order);
          System.out.println("更新orders 成功");
        }
      };

      //add collect
      Consumer consumer7 = new DefaultConsumer(channel) {
        @Override
        public void handleDelivery(String consumerTag, Envelope envelope,
            BasicProperties properties, byte[] body) throws IOException {
          String json = new String(body);
          Collect collect = Gsonal.fromJson(json, Collect.class);
          int temp = 0;
          collect = collectDao.findCollect(collect.getUid(), collect.getPid());
          if (collect != null) {
            temp = 1;
          }
          if (temp == 0) {
            collectDao.addcollect(collect);
            System.out.println("add collect  操作成功");
          }
        }
      };

      //del collect
      Consumer consumer8 = new DefaultConsumer(channel) {
        @Override
        public void handleDelivery(String consumerTag, Envelope envelope,
            BasicProperties properties,
            byte[] body) throws IOException {
          String json = new String(body);
          Collect collect = Gsonal.fromJson(json, Collect.class);
          collectDao.delCollect(collect);
          System.out.println("del collect  操作成功");
        }
      };

      channel.basicQos(2,false);
      channel.basicQos(4,true);
      channel.basicConsume(Queue_Add, false, consumer1);
      channel.basicConsume(Queue_Del, false, consumer2);
      channel.basicConsume(Queue_Email, true, consumer3);
      channel.basicConsume(ForgetPassword, true, consumer4);
      channel.basicConsume(Update_Product, true, consumer5);
      channel.basicConsume(Update_Orders, true, consumer6);
      channel.basicConsume(Add_Collect, true, consumer7);
      channel.basicConsume(Del_Collect, true, consumer8);

    } catch (IOException e) {
      e.printStackTrace();
    } catch (TimeoutException e) {
      e.printStackTrace();
    }
  }
}
